﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HtmlAgilityPack;
using NPOI.HSSF.UserModel;
using Test;
using HtmlDocument = HtmlAgilityPack.HtmlDocument;
using System.IO;

namespace WebForm {
    public partial class Gumtree : Form {
        private List<Infors> m_infos; 
        private object m_locker= new object();
        public Gumtree() {
            InitializeComponent();
            webBrowser1.ScriptErrorsSuppressed = true;
            m_infos = new List<Infors>();
        }

        private void button1_Click(object sender, EventArgs e) {
            m_infos.Clear();
            if (string.IsNullOrEmpty(textBox1.Text) || string.IsNullOrEmpty(textBox2.Text)) {
                MessageBox.Show("Please input category address & output directory", "Warning!", MessageBoxButtons.OK);
                return;
            }
            if (!Directory.Exists(textBox2.Text)) {
                MessageBox.Show("Ouput path is not valid!", "Warning!", MessageBoxButtons.OK);
                return;
            }
            // hlisting offer-sale 
            listBox1.Items.Clear();
            AA:
            webBrowser1.Navigate(textBox1.Text);
            DateTime process = DateTime.Now;
            while (webBrowser1.ReadyState != WebBrowserReadyState.Complete) {
                Application.DoEvents();
                if (DateTime.Now.Subtract(process).Minutes > 2) {
                    goto AA;
                }
            }

            var doc = new HtmlDocument();
            doc.LoadHtml(webBrowser1.DocumentText);

            var searchNode = doc.DocumentNode.SelectSingleNode("//div[contains(@id,'search-results')]");
            List<string> detailUrls = new List<string>();
            if (searchNode != null) {
                var prodNodes =
                    searchNode.SelectNodes(".//li[contains(@class,'hlisting') and contains(@class,'offer-sale')]");
                if (prodNodes != null) {
                    foreach (var prodNode in prodNodes) {
                        var link = prodNode.SelectSingleNode("./a[contains(@class,'description')]");
                        if (link != null) {
                            detailUrls.Add(link.GetAttributeValue("href",string.Empty));
                        }
                    }
                    toolStripProgressBar1.Value = 1;
                    int value = 0;
                    //List<Task<Infors>> tasks = new List<Task<Infors>>();
                    foreach (var url in detailUrls) {
                        value++;
                        Infors info = GetDataInfor(url);
                        //tasks.Add(GetDataInfor(url));
                        if (info != null && !string.IsNullOrEmpty(info.Number)) {
                            info.OrginalUrl = url;
                            lock (m_locker) {
                                m_infos.Add(info);
                            }
                            listBox1.Items.Add(info.Number);
                            listBox1.Refresh();
                        }
                        toolStripProgressBar1.Value = (value * 100) / detailUrls.Count;
                    }
                }
            }
            Save();
            MessageBox.Show("Finish!");
        }
        private Infors GetDataInfor(string urlDetail) {
            if (string.IsNullOrEmpty(urlDetail)) {
                return null;
            }
            var web = new HtmlWeb();

            HtmlDocument doc = web.Load(urlDetail);
            Infors info = new Infors();
            var name = doc.DocumentNode.SelectSingleNode("//h1[contains(@id,'primary-h1')]");
            if (name != null) {
                info.Name = name.InnerText;
            }
            var number =
                doc.DocumentNode.SelectSingleNode(
                    "//div[contains(@class,'main-content-wrapper')]//span[contains(@class,'contact-phone-number-obscured')]");
            if (number != null) {
                info.Number = number.GetAttributeValue("reveal-number", string.Empty);
            }
            return info;

        }
        private void Save() {
            var workbook = new HSSFWorkbook();
            var sheet = workbook.CreateSheet("Gumtree");
            var headerRow = sheet.CreateRow(0);
            headerRow.CreateCell(0).SetCellValue("Product Name");
            headerRow.CreateCell(1).SetCellValue("Phone No");
            headerRow.CreateCell(2).SetCellValue("Original Url");
            NPOI.SS.Util.CellRangeAddress cra = new NPOI.SS.Util.CellRangeAddress(0, 0, 4, 6);
            sheet.AddMergedRegion(cra);
            lock (m_locker) {
                for (int i = 0; i < m_infos.Count; i++) {
                    var company = m_infos[i];
                    var row = sheet.CreateRow(i + 1);
                    row.CreateCell(0).SetCellValue(company.Name);
                    row.CreateCell(1).SetCellValue(company.Number);
                    row.CreateCell(2).SetCellValue(company.OrginalUrl);
                }
               m_infos.Clear();
            }
            try {
                string fileName = Path.Combine(textBox2.Text, string.Format("gumtree.xls"));
                
                using (var file = new FileStream(fileName, FileMode.Create)) {
                    workbook.Write(file);
                    file.Flush();
                    file.Close();
                }
            } catch (Exception ex) {

                MessageBox.Show(ex.Message, "Error!");
            }
        }
        private void button2_Click(object sender, EventArgs e) {
            var dialog = new FolderBrowserDialog();
            if (dialog.ShowDialog() == DialogResult.OK) {
                textBox2.Text = dialog.SelectedPath;
            }
        }
    }
    public class Infors {
        public string Name { get; set; }
        public string Number { get; set; }
        public string OrginalUrl { get; set; }
    }
}
